<template>
  <el-dialog :visible.sync="visible"
             @click.native="roleVisible = false"
             title="权限设置"
             :close-on-click-modal="false"
             :append-to-body="true"
             :before-close="closeDialog"
             label-position="top"
             class="add-or-updata"
             width="35%"
             :close-on-press-escape="false">
    <div class="role">
      <div style="margin-bottom: 10px;">选择角色</div>
      <!-- <el-checkbox-group v-model="checkList"
                         @change="handleCheckedRoleNameChange">
        <el-checkbox v-for="item in roleList"
                     :key="item.id"
                     :label="item.id">{{item.roleName}}</el-checkbox>
      </el-checkbox-group> -->
      <el-select v-model="checkList"
                 multiple
                 @change="handleCheckedRoleNameChange"
                 placeholder="请选择角色">
        <el-option v-for="item in roleList"
                   :key="item.id"
                   :label="item.roleName"
                   :value="item.id">
        </el-option>
      </el-select>
      <div class="appBtn">
        <div style="color:red;line-height:28px;font-size:12px">说明：选择角色后请点击获取权限按钮</div>
        <el-button type="primary"
                   size="mini"
                   @click="applicationPermissions">获取权限</el-button>
      </div>
    </div>
    <div class="perission-header">
      <div class="perission-header-title">选择权限</div>
      <el-button type="primary"
                 size="mini"
                 plain
                 @click="openSyncPermisssions">同步权限</el-button>
    </div>
    <div class="rule-list-box"
         v-loading='ruleLoading'>
      <div class="rule-list">
        <el-tree :data="ruleTree"
                 show-checkbox
                 default-expand-all
                 ref="ruleTree"
                 :check-strictly="true"
                 :props="defaultProps"
                 @check-change="ruleChange"
                 node-key="id">
          <span class="custom-tree-node"
                slot-scope="{ node, data }">
            <span>{{ node.label }}</span>
            <span v-if="isAllCheck(data)"
                  class="margin-left-10">
              <el-button type="text"
                         size="mini"
                         @click.stop="setCheckAll(data)">
                全选
              </el-button>
            </span>
          </span>
        </el-tree>
      </div>
    </div>
    <template slot="footer">
      <el-button type="primary"
                 :loading="ruleLoading"
                 @click="dataFormSubmitHandle()"
                 v-if="$hasPermission('system:sysUser:manyBinding')"
                 :disabled="enableConfig">{{ $t('confirm') }}</el-button>
      <el-button @click="closeDialog">{{ $t('cancel') }}</el-button>
    </template>
    <sync-permissions ref="syncPermissions"
                      @callBack="getSyncPermissions" />
  </el-dialog>
</template>

<script>
import mixinViewModule from '@/mixins/view-module'
import formValidate from '@/mixins/form-validate'
import debounce from 'lodash/debounce'
import Qs from 'qs'
// import dataTree from '@/utils/data'
import syncPermissions from './sync-permissions'
export default {
  mixins: [mixinViewModule, formValidate],
  data () {
    return {
      visible: false,
      enableConfig: false, // 确认之后禁用掉按钮，等操作成功之后恢复
      mixinViewModuleOptions: {
        refreshPermissionsURL: '/system/sysPermission/refreshPermissions', // 更新权限
        getDataInfoURL: '/system/sysPermission/getById?id=', // 获取角色管理的详情
        getRoleListURL: '/sys/role/allPermission', // 根据用户id获取对应的菜单树结构
        addOrUpdateURL: '/system/sysUser/manyBinding' // 新增或添加的接口
      },
      roleVisible: false,
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      checked: '',
      checkList: [],
      roleList: [],
      username: '',
      actionItems: [], // 选中的菜单id
      ruleLoading: false,
      actionRules: {},
      deletRules: [],
      ruleTree: [],
      roleTree: [],
      dataForm: {
        userIds: [],
        perIds: [],
        roleIds: []
      },
      val: []
    }
  },
  components: {
    syncPermissions
  },
  computed: {
    isAllCheck () {
      return (val) => {
        return !!val.children.length
      }
    }
  },
  methods: {
    closeDialog () {
      this.visible = false
      this.ruleLoading = false
      this.checkList = []
      this.ruleTree = []
      this.roleList = []
      this.val = []
    },
    init (data) {
      data = data || {}
      data.map((res) => {
        this.dataForm.userIds.push(res.id)
      })
      this.visible = true
      this.ruleLoading = false
      this.username = data.username
      this.actionItems = []
      this.roleTree = []
      this.ruleTree = []
      this.dataForm.perIds = []
      this.deletRules = []
      this.getRoleList()
      this.getPerList()
      // this.roleTree.push(...data.list)
      this.$nextTick(() => {
        if (this.dataForm.userId) {
          // this.getRuleList() // 测试
          // this.getInfo()
        }
      })
    },
    // 获取角色
    getRoleList () {
      this.$http.get('/sys/role/getRoleAll').then(({ data: res }) => {
        this.roleList = res.data
      })
    },
    handleCheckedRoleNameChange (value) {
      this.dataForm.roleIds = value
      this.roleIds = value.join()
    },
    // 应用权限
    applicationPermissions () {
      // console.log(this.roleIds, 999)
      this.ruleLoading = true
      this.$http.get(`/sys/role/perRoleList?roleIds=${this.roleIds}`).then(({ data: res }) => {
        if (res.code !== 0) {
          return
        }
        this.selectMenu(res.data)
        this.ruleLoading = false
      })
    },
    // 打开同步权限窗口
    openSyncPermisssions () {
      this.$refs.syncPermissions.init()
    },
    // 全选
    setCheckAll (node) {
      // 获取选中菜单的所有子级
      this.ruleLoading = true
      const ids = this.getCheckMenuChildren(node, true)
      const temp = this.actionItems.concat(ids)
      this.actionItems = []
      this.actionItems.push(...new Set(temp))
      setTimeout(() => {
        this.$refs.ruleTree.setCheckedKeys(this.actionItems)
        this.ruleLoading = false
      }, 300)
    },
    // 修改获取的权限
    ruleChange (node, check) {
      this.dataForm.perIds = []
      this.deletRules = []
      let rules = JSON.parse(JSON.stringify(this.actionRules))

      // 是否选中
      if (check) {
        // 获取当前选中菜单的顶级目录
        const topItem = this.ruleTree.filter(item => item.id === node.topId || item.id === node.id)
        // 获取当前菜单的所有父级id，将当前选中菜单的父级id和之前的id进行并和
        const ids = this.getMenuParant(node.id, topItem, topItem)
        const temp = this.actionItems.concat(ids)
        // 清空当前选中的菜单数组并添加新的数据选中菜单数据
        this.actionItems = []
        this.actionItems.push(...new Set(temp))
      } else {
        // 获取选中的菜单的已选中的子级
        const deleteList = this.getCheckMenuChildren(node)
        deleteList.map(deletItem => {
          this.actionItems.map((item, index) => {
            if (item === deletItem) {
              this.actionItems.splice(index, 1)
            }
          })
        })
      }

      this.actionItems.map(item => {
        this.dataForm.perIds.push(item)

        if (rules[item]) {
          delete rules[item]
        }
      })

      this.deletRules.push(...Object.values(rules))
      this.$refs.ruleTree.setCheckedKeys(this.actionItems)
    },
    // 获取同步权限的用户权限信息
    getSyncPermissions (data) {
      this.selectMenu(data)
    },
    // 根据上级用户id获取对应的菜单树结构
    getPerList () {
      this.ruleLoading = true
      this.$http.get('/sys/role/allPermission').then(res => {
        this.selectMenu(res.data.data)
        this.ruleLoading = false
      })
    },
    // 设置已选中的菜单权限
    selectMenu (data) {
      this.ruleTree = []
      this.actionRules = {}
      this.ruleLoading = false
      this.$refs.ruleTree.setCheckedKeys([])
      this.dataForm.perIds = []
      this.actionItems = []

      this.getSelectMenu(data)
      this.$refs.ruleTree.setCheckedKeys(Object.values(this.actionRules), true)
      this.ruleTree.push(...data)
    },
    /**
     * @method: getCheckMenuChildren
     * @msg: 递归查找当前选中菜单的下级
     * @param  {Object} actionItem  // 选中的菜单项
     * @param  {Boolean} allChildren  // 是否获取该选中菜单的所有子级， 默认false
     * @param  {Array} ids  // 选中菜单项的ids
     * @return {Array} ids
     */
    getCheckMenuChildren (actionItem, allChildren, ids) {
      ids = ids || []
      let filterItem = []
      ids.push(actionItem.id)

      actionItem.children.map(childrenItem => {
        if (!allChildren) {
          filterItem = this.actionItems.filter(item => item === childrenItem.id)
        }

        if (filterItem.length || allChildren) {
          ids = this.getCheckMenuChildren(childrenItem, !!allChildren, ids)
        }
      })

      return ids
    },
    // 递归查找当前选中菜单的所有父级
    getMenuParant (id, list, initialList, ids) {
      ids = ids || []

      for (var i = 0; i < list.length; i++) {
        var item = list[i]
        if (item.id === id) {
          ids.push(item.id)

          this.getMenuParant(item.pid, initialList, initialList, ids)
          break
        } else {
          if (item.children.length) {
            this.getMenuParant(id, item.children, initialList, ids)
          }
        }
      }
      return ids
    },
    // 递归查询已勾选的菜单权限
    getSelectMenu (list) {
      list.map(item => {
        if (item.sign) {
          this.$set(this.actionRules, item.id, item.id)
          this.actionItems.push(item.id)
          this.dataForm.perIds.push(item.id)
        }
        if (item.children.length) {
          this.getSelectMenu(item.children)
        }
      })
    },
    // 获取信息
    getInfo () {
      this.getDataInfo().then(res => {
        if (res.code !== 0) { return false }
        // this.dataForm.pid = res.data.pid
        // this.dataForm.roleName = res.data.parentName
        this.getRuleList()
        if (res.data.pid === '0') {
          this.dataForm.pid = '0'
          this.dataForm.roleName = 'admin'
        }
      })
    },
    // 表单提交
    dataFormSubmitHandle: debounce(function () {
      // const url = this.mixinViewModuleOptions.addOrUpdateURL
      // this.addOrUpdateItem({ url }).then(res => {
      //   if (res.code !== 0) { return }
      //   this.closeDialog()
      //   this.$emit('callBack')
      // })
      this.ruleLoading = true
      this.dataForm.perIds = this.dataForm.perIds.join()
      this.dataForm.userIds = this.dataForm.userIds.join()
      if (this.dataForm.roleIds.length !== 0) {
        this.dataForm.roleIds = this.dataForm.roleIds.join()
      }
      this.$http.post(this.mixinViewModuleOptions.addOrUpdateURL, Qs.stringify(this.dataForm))
        .then(({ data: res }) => {
          if (res.code !== 0) {
            return
          }
          this.$message({
            message: this.$t('prompt.success'),
            type: 'success',
            duration: 500
          })
          this.closeDialog()
          this.$emit('callBack')
        })
    }, 1000, { 'leading': true, 'trailing': false })
  }
}
</script>
<style lang="scss" scoped>
.rule-list-box {
  position: relative;
  width: 100%;
  height: 350px;
  overflow: hidden;
  .rule-list {
    position: absolute;
    top: 0;
    left: 0;
    width: 105%;
    max-height: 350px;
    overflow: hidden;
    overflow-y: auto;
  }
}
.perission-header {
  display: flex;
  align-items: center;
  margin-bottom: 15px;
  .perission-header-title {
    margin-right: 15px;
  }
}
.role {
  padding-bottom: 20px;
  .el-select {
    width: 100%;
  }
  .appBtn {
    margin-top: 10px;
    // text-align: right;
    display: flex;
    justify-content: space-between;
  }
}
</style>
